import mediapipe as mp
import cv2
import numpy as np


class Hands:
    def __init__(self):
        self.mp_hands = mp.solutions.hands.Hands()
        self.frame = None
        self.landmarks = []
        pass
    def draw_style(self, frame):
        mp_hands = self.mp_hands

        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        result = mp_hands.process(frame_rgb)
        hand_landmarks_list = result.multi_hand_landmarks
        if hand_landmarks_list is None:
            return
        landmarks = hand_landmarks_list[0]
        hand_landmarks = landmarks.landmark
        self.landmarks = hand_landmarks
        # 链接点
        conns = mp.solutions.hands_connections.HAND_CONNECTIONS
        # 关键点样式
        hands_style = mp.solutions.drawing_utils.DrawingSpec(color=(0,0,255),thickness=2)
        conns_style = mp.solutions.drawing_utils.DrawingSpec(color=(0,0,0),thickness=2)


        mp.solutions.drawing_utils.draw_landmarks(
            image=frame,
            landmark_list=landmarks,
            connections=conns,
            landmark_drawing_spec=hands_style,
            connection_drawing_spec=conns_style,
        )
        pass
        # 进行关键点样式的绘制
        frame_h, frame_w, _ = frame.shape
        for index, lm in enumerate(hand_landmarks):
            x = round(lm.x * frame_w)
            y = round(lm.y * frame_h)
            # 关键点序号的绘制
            cv2.putText(frame, str(index), (x, y), fontFace=cv2.FONT_ITALIC,fontScale=0.45,color=(0,0,0),thickness=1)
            # print(index, x, y)
       # 手势数字识别
    def gesture_num(self):
        # 用Y坐标判断

        top_point_num = [4, 8, 12, 16, 20]
        finger_status = np.zeros((5,),dtype=np.int8)
        for index,num in enumerate(top_point_num):
            if index == 0:

                continue
            top_p = self.index_convert_num(num)[1]
            mid_p = self.index_convert_num(num-1)[1]
            # 未弯曲
            finger_status[index] = top_p < mid_p
            # 弯曲
            if top_p > mid_p:
                print(index,top_p,mid_p)
        cnt = np.sum(finger_status)
        cv2.putText(self.frame, str(cnt), (20,100), fontFace=cv2.FONT_ITALIC,fontScale=0.45,color=(0,255,0),thickness=1)

        pass
    def index_convert_num(self,index):
        frame_h, frame_w, _ = self.frame.shape
        lm = self.landmarks[index]
        x = round(lm.x * frame_w)
        y = round(lm.y * frame_h)
        return x,y
    def process(self,frame):
        self.frame = frame
        self.draw_style(self.frame)
        self.gesture_num()
        pass

if __name__ == '__main__':
    mp_hands = Hands()
    cap = cv2.VideoCapture(0)
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        # 进行关键点检查
        mp_hands.process(frame)
        cv2.imshow('hands', frame)
        key = cv2.waitKey(60)
        if key == 'q':
            break
    cap.release()
    cv2.destroyAllWindows()
